package com.artnology.independence.views.jung;

import java.awt.event.MouseEvent;
import java.awt.event.MouseWheelEvent;
import java.awt.event.MouseWheelListener;
import java.awt.geom.Point2D;

import edu.uci.ics.jung.visualization.Layer;
import edu.uci.ics.jung.visualization.VisualizationViewer;
import edu.uci.ics.jung.visualization.control.AbstractGraphMousePlugin;
import edu.uci.ics.jung.visualization.control.ScalingControl;
import edu.uci.ics.jung.visualization.transform.MutableTransformer;

public class ScalingGraphMousePlugin extends AbstractGraphMousePlugin implements
		MouseWheelListener {
	protected float in;
	protected float out;
	protected boolean zoomAtMouse;
	protected ScalingControl scaler;

	public ScalingGraphMousePlugin(ScalingControl scaler, int modifiers) {
		this(scaler, modifiers, 1.1F, 0.9090909F);
	}

	public ScalingGraphMousePlugin(ScalingControl scaler, int modifiers,
			float in, float out) {
		super(modifiers);

		this.in = 1.1F;

		this.out = 0.9090909F;

		this.zoomAtMouse = true;

		this.scaler = scaler;
		this.in = in;
		this.out = out;
	}

	public void setZoomAtMouse(boolean zoomAtMouse) {
		this.zoomAtMouse = zoomAtMouse;
	}

	public boolean checkModifiers(MouseEvent e) {
		return ((e.getModifiers() == this.modifiers) || ((e.getModifiers() & this.modifiers) != 0));
	}

	public void mouseWheelMoved(MouseWheelEvent e) {

		boolean accepted = checkModifiers(e);
		if (accepted == true) {
			VisualizationViewer vv = (VisualizationViewer) e.getSource();

			MutableTransformer viewTransformer = vv.getRenderContext()
					.getMultiLayerTransformer().getTransformer(Layer.VIEW);

			// required to prevent fatal eclipse crash when zooming out too far
			boolean stillAllowedToZoomOut = viewTransformer.getScale() > 0.05f;
			
				Point2D mouse = e.getPoint();
				Point2D center = vv.getCenter();
				int amount = e.getWheelRotation();
				if (this.zoomAtMouse) {
					if (amount > 0)
						this.scaler.scale(vv, this.in, mouse);
					else if (amount < 0 && stillAllowedToZoomOut) {
						this.scaler.scale(vv, this.out, mouse);
					}
				} else if (amount > 0)
					this.scaler.scale(vv, this.in, center);
				else if (amount < 0 && stillAllowedToZoomOut) {
					this.scaler.scale(vv, this.out, center);
				}
			

			e.consume();
			vv.repaint();
		}
	}

	public float getIn() {
		return this.in;
	}

	public void setIn(float in) {
		this.in = in;
	}

	public float getOut() {
		return this.out;
	}

	public void setOut(float out) {
		this.out = out;
	}

	public ScalingControl getScaler() {
		return this.scaler;
	}

	public void setScaler(ScalingControl scaler) {
		this.scaler = scaler;
	}
}